package com.woniu.user.controller;

import com.woniu.common.constant.RedisKeyConstant;
import com.woniu.common.entity.Result;
import com.woniu.common.entity.ResultCode;
import com.woniu.common.utils.JwtUtil;
import com.woniu.common.utils.MobileUtil;
import com.woniu.common.utils.SendSmsUtil;
import com.woniu.user.dto.UserLoginDTO;
import com.woniu.user.dto.UserRegisterDTO;
import com.woniu.user.pojo.User;
import com.woniu.user.service.IUserService;
import com.woniu.user.vo.UserLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author hushunlai
 * @since 2023-05-22
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户管理")
//动态感知刷新
@RefreshScope
public class UserController {

    @Autowired
    private IUserService userService;

    @Value("${web.mode.test}")
    private Boolean test;

    @Value("${jwt.expiration}")
    private Long expiration;

    @Autowired
    private RedisTemplate redisTemplate;


    @GetMapping("/get/{id}")
    @ApiOperation("根据id获取单个user对象")
    public Result<User> getUser(@PathVariable Integer id) {
        User byId = userService.getById(id);
        return Result.ok(byId);
    }

    @GetMapping("/list")
    @ApiOperation("获取所有user对象")
    public Result<List<User>> listUser() {
        List<User> userList = userService.list();
        return Result.ok(userList);
    }

    @PostMapping("/register/{action}")
    @ApiOperation("注册")
    public Result register(@PathVariable String action, @RequestBody UserRegisterDTO userRegisterDTO) {
        //参数规则校验
        //判断验证码是否正确
        //判断短信验证码-是否为空
        String code = userRegisterDTO.getCode();
        if (org.springframework.util.StringUtils.isEmpty(code)) {
            return Result.error();
        }
        //判断验证码是否有值
        String redisCode = (String) redisTemplate.opsForValue().get("code" + action + "_" + userRegisterDTO.getMobile());
        if (redisCode == null || !redisCode.equals(code)) {
            return Result.error("验证码错误或者不存在");
        }
        // 删除redis中的验证码
        redisTemplate.delete("code_register_" + userRegisterDTO.getMobile());
        if (!test) {
            //非演示模式进行验证码验证
            if (StringUtils.isEmpty(userRegisterDTO.getCode()) || !"1234".equals(userRegisterDTO.getCode())) {
                return Result.error(ResultCode.CODE_ERROR.getCode(), ResultCode.CODE_ERROR.getMessage());
            }
        }
        //调用service注册方法
        userService.register(userRegisterDTO);
        return Result.ok();
    }

    @PostMapping("/login/{action}")
    @ApiOperation("登录")
    public Result<UserLoginVO> login(@PathVariable String action, @RequestBody(required = false) UserLoginDTO userLoginDTO) {
        //对数据校验
        UserLoginVO userLoginVO = null;

        //对不同的登录方式调用不同的方法（调用service进行登录操作）
        if (userLoginDTO.getType() == 0) {
            //账号密码
            userLoginVO = userService.loginByPassword(userLoginDTO.getMobile(), userLoginDTO.getPassword());
        }
        //手机号是否为空
        if (userLoginDTO.getMobile() == null) {
            return Result.error();
        }
        //判断登录成功还是失败
        if (userLoginVO == null) {
            return Result.error(ResultCode.USER_LOGIN_ERROR.getCode(), ResultCode.USER_LOGIN_ERROR.getMessage());
        }
        //使用JWT创建一个token，将token存在redis中并设置过期时间
        Map<String, Object> map = new HashMap<>();
        map.put("mobile", userLoginVO.getMobile());
        String token = JwtUtil.createJWT(userLoginVO.getId() + "", map, expiration * 60 * 1000);
        redisTemplate.opsForValue().set(RedisKeyConstant.LOGIN_TOKEN + userLoginVO.getMobile() + "", token, expiration * 60 * 1000, TimeUnit.SECONDS);
        //响应数据（VO中存了token来响应）
        userLoginVO.setToken(token);
        return Result.ok(userLoginVO);
    }

    @GetMapping("/sendSms/{mobile}/{action}")
    @ResponseBody
    @ApiOperation("手机发送短信验证")
    public Result sendSmsCode(@PathVariable String mobile, @PathVariable String action) {
        //校验手机号码是否正确
        boolean flag = MobileUtil.checkPhone(mobile);
        if (!flag) {
            return Result.error();
        }
        // 判断该手机号码该在场景有没有没有过期的短信，有过期的短信，不发了。 如果没有，发送短信
        Object redisCode = redisTemplate.opsForValue().get("code_" + action + "_" + mobile);
        if (redisCode != null) {
            return Result.error("验证码已发送，请稍后再试");
        }

        //生成短信验证码
        String code = SendSmsUtil.getRandomNum(4);
        redisTemplate.opsForValue().set("code" + action + "_" + mobile, code, 1 * 60, TimeUnit.SECONDS);
        //调用工具类发送短信
        SendSmsUtil.sendSms(mobile, code);
        System.out.println(code);
        // 5. 响应数据
        return Result.ok();
    }

    @GetMapping("/mobile/{mobile}")
    @ApiOperation("获取手机号")
    public Result<UserLoginVO> getByMobile(@PathVariable String mobile) {
        UserLoginVO userLoginVO = userService.getByMobile(mobile);
        return Result.ok(userLoginVO);
    }

    @GetMapping("/updateAmount/{mobile}/{amount}")
    @ApiOperation("修改比特币数量")
    public Result updateAmount(@PathVariable("mobile") String mobile,
                               @PathVariable("amount") BigDecimal amount) {
        userService.updateAmount(mobile, amount);
        return Result.ok();
    }

    /**
     * 增加比特币
     *
     * @param mobile
     * @param amount
     * @return
     */
    @GetMapping("/addAmount/{mobile}/{amount}")
    @ApiOperation("增加比特币数量")
    public Result addAmount(@PathVariable("mobile") String mobile,
                            @PathVariable("amount") BigDecimal amount) {
        userService.addAmount(mobile, amount);
        return Result.ok();
    }

    @GetMapping("/updateStoreId/{storeId}/{mobile}")
    @ApiOperation("修改用户表中的商家Id")
    public Result updateStoreId(@PathVariable("storeId") Integer storeId,
                                @PathVariable("mobile") String mobile) {
        userService.updateStoreId(storeId, mobile);
        return Result.ok();
    }
}
